/*
 * @Author: dadadaXU 1413107032@qq.com
 * @Date: 2025-01-03 23:07:27
 * @LastEditors: dadadaXU 1413107032@qq.com
 * @LastEditTime: 2025-01-05 10:29:53
 * @FilePath: /FileBackup/src/FileBackup.cpp
 * @Description: 应用程序类，集成其他功能类
 */

#include "../include/FileBackup.hpp"

Application::Application(int argc, char **argv)
    : m_argc(argc), m_argv(argv)
{
    if (argc < 2)
    {
        std::cout << "Usage: fbk [OPTION...]" << std::endl
                  << "Try 'fbk --help' for more information." << std::endl;
        ::exit(EXIT_FAILURE);
    }
    parser = nullptr;
    packer = nullptr;
    compressor = nullptr;
}

Application::~Application()
{
    if (parser != nullptr)
    {
        delete parser;
        parser = nullptr;
    }
    if (packer != nullptr)
    {
        delete packer;
        packer = nullptr;
    }
    if (compressor != nullptr)
    {
        delete compressor;
        compressor = nullptr;
    }
}

bool Application::run()
{
    parser = new CArgumentsParser();
    if (!parser->Parse(m_argc, m_argv))
        return false;

    if (parser->userFlag.help)
        return true;
    /* 数据备份 */
    else if (parser->userFlag.backup)
    {
        packer = new FilePacker(parser->inputPath, parser->outputPath);
        packer->PackFile(parser->fileFilterArguments, parser->message);

        /* 在打包基础上进行压缩 */
        if (parser->userFlag.compress)
        {
            std::filesystem::path packer_file(parser->outputPath);
            packer_file.replace_extension(FILE_SUFFIX_PACK);
            if (!std::filesystem::exists(packer_file))
            {
                std::cerr << "Miss file path:" << packer_file << std::endl;
                return false;
            }

            compressor = new FileCompressor(packer_file, parser->outputPath);
            if (!compressor->Compress())
                return false;

            /* 删除压缩前的打包文件 */
            if (parser->userFlag.deleteFile && !std::filesystem::remove(packer_file))
            {
                std::cerr << "Remove file failed: " << packer_file << std::endl;
                return false;
            }
        }
    }
    /* 数据恢复 */
    else if (parser->userFlag.restore)
    {
        std::string suffix = parser->inputPath.extension();
        if (suffix == FILE_SUFFIX_COMPRESS)
        {
            compressor = new FileCompressor(parser->inputPath, parser->outputPath);
            if (!compressor->Decompress(parser->userFlag.goBack))
                return false;

            /* 解压后继续解包 */
            if (std::filesystem::exists(compressor->targetFilePath) &&
                compressor->targetFilePath.extension() == FILE_SUFFIX_PACK)
            {
                packer = new FilePacker(compressor->targetFilePath, parser->outputPath);
                if (!packer->UnpackFile(parser->userFlag.metadata, parser->userFlag.goBack))
                    return false;

                /* 删除的打包文件 */
                if (!std::filesystem::remove(compressor->targetFilePath))
                {
                    std::cerr << "Remove file failed: " << compressor->targetFilePath << std::endl;
                    return false;
                }
            }
        }
        if (suffix == FILE_SUFFIX_PACK)
        {
            packer = new FilePacker(parser->inputPath, parser->outputPath);
            if (!packer->UnpackFile(parser->userFlag.metadata, parser->userFlag.goBack))
                return false;
        }

        /* 删除解包原始文件 */
        if (parser->userFlag.deleteFile && !std::filesystem::remove(parser->inputPath))
        {
            std::cerr << "Remove file failed: " << parser->inputPath << std::endl;
            return false;
        }
    }
    /* 查看信息 */
    else if (parser->userFlag.viewInfo)
    {
        // TODO 查看所有打包文件
        std::string suffix = parser->viewInfoPath.extension();
        if (suffix == FILE_SUFFIX_COMPRESS)
        {
            FileBaseUnit compress_file(parser->viewInfoPath);
            CompressHeader compress_header = {0};
            if (!compress_file.ReadCompressHeader(compress_header))
                return false;
            /* 显示文件头信息 */
            std::cout << "Compress file path: " << compress_header.filePath << std::endl
                      << "\tfile CRC code: " << compress_header.CRC << std::endl
                      << "\theader offset: " << compress_header.offset << std::endl
                      << "\toriginal size: " << compress_header.fileSize << std::endl;
        }
        if (suffix == FILE_SUFFIX_PACK)
        {
            FileBaseUnit backup_file(parser->viewInfoPath);
            BackupHeader backup_header = {0};
            if (!backup_file.ReadBackupHeader(backup_header))
                return false;
            /* 显示文件头信息 */
            std::cout << "Backup file path: " << backup_header.filePath << std::endl
                      << "\tfile CRC code: " << backup_header.CRC << std::endl
                      << "\theader offset: " << backup_header.offset << std::endl
                      << "\tadded message: " << backup_header.message << std::endl;
        }
    }

    return true;
}

#ifndef GTEST_API_ // gtest 测试模块忽略

int main(int argc, char **argv)
{
    Application app(argc, argv);
    if (!app.run())
        return -1;

    return 0;
}

#endif